<style>
h1 {font-size:20;} h2 {font-size:16;} h3 {font-size:12;} h4 {font-size:8;} h5 {font-size:4;} h6 {font-size:2;}
</style>
<pre>
<?php
set_time_limit(1500);
require_once("include.php");
require_once("workobj.php");
global $workers,$employees,$skills,$order ,$stock,$subbprods,$products,$cnt,$depends ,$dependsqty;
$stock = array();
$startwork = time();
$cnt = sqlread("select max(itemid) from work");
$cnt = $cnt[0]+1;
// Who can make stuff
$sql = ("select itemid,name from employee ");
$employees = sqlreadkeyarray($sql);
// Take off holidays and non working hours
takeoutoffwork();
// What can they make
$temp = sqlreadarray("select processid,employeeid from skillmatch");
$skills = array();
foreach ($temp as $tempitem) {
 $processid = $tempitem[0]; $employeeid = $tempitem[1];
 $skills[$processid][] = $employeeid;
}
// What needs to be made
$work = sqlreadarray("select * from sorderline");
foreach($work as $line) {
 $prod = $line[5];
 $qty = $line[3];
 $order = $line[0]."-".$line[1];
 for ($i = 0 ; $i < $qty; $i++) {
  list($eft,$sublist) = drill($prod,$cnt,1);
  echo $order." ";
  echo date("Y-m-d H:i:s",$eft)."\n";
 }
}
write();

function drill($productid,$cnt,$qty) {
 global $employees,$skills,$work,$order,$stock,$subprods,$products,$cnt,$depends,$dependsqty;
 $sublist = array();
 $eft = time();
 if (isset($stock[$productid])) {
  $avail = $stock[$productid]-$qty;
 } else {
  $sql = "select qty from stock where branch = 1 and product = '$productid'";
  $avail = sqlreaditem($sql)-$qty;
 }
 $stock[$productid] = $avail;

 if ($avail < 0) {
  $productitem = @$products[$productid];
  if ($productitem == NULL) {
   $productitem = freaditem("product",$productid);
   $products[$productid] = $productitem;
  }
  
  $skill = $productitem[18];

  if($skill) {
   // It has some work to put together sub products
   // Cache to save bothering the DB
   $subs = @$subprods[$productid];
   if ($subs == NULL) {
    $sql = "select subproduct,quantity from productbuilds where itemid='$productid'";
    $subs = sqlreadarray($sql);
    $subprods[$productid] = $subs;
   }
  
   // Go through the sub products recursively
   for ($i=$avail;$i<0;$i++) {
    foreach ($subs as $item) {
     $newcode = $item[0]; $newqty = $item[1]*$qty;
     list($thiseft,$subitem) = drill($newcode,$cnt+1,$newqty);
     $sublist[] = $subitem;
     if ($thiseft > $eft) {$eft = $thiseft;}
    }
   }
   // Then deal with this product.
   // The earliest we can start is $eft.
   
   $duration = $productitem[23];
   $drying = $productitem[25];
    // Find who can do this work soonest
   $bestemployee = 'NOBODYCANDOIT';
	 $soonest = strtotime('2020-12-31 00:00:00');
	 $elist = $skills[$skill];  // A list of employees who possess the correct skill
 	 // Go through those who have the skills
   foreach($elist as $employeeid) {
    // Find a gap of duration length which starts after $eft
    $lastfrm = $eft;
    $subarray = $employees[$employeeid][2];
    // Go through the spare times for those employees
    foreach ($subarray as $fromdate=>$dateitem) {
     if ($fromdate-$lastfrm > $duration*60) {
      // Found the soonest gap for this employee. Assigned to $lastfrm 
      break ;
     } else {
      $lastfrm = max($dateitem['FINISHTIME'],$eft);
     }
    }     
    if ($lastfrm < $soonest) {
     $soonest = $lastfrm;
     $bestemployee = $employeeid ;
    }
   } 
   // Add item to array
	 $cnt = $cnt + 1;
	 $newitem = array('MAKE'=>$productid,'SKILL'=>$skill,'ORDERLINE'=>$order,'FINISHTIME'=>$soonest+$duration*60,'CNT'=>$cnt);
   foreach ($sublist as $subid) {$depends[$subid] = $cnt;}
   $dependsqty[$cnt] = $qty;
   $employees[$bestemployee][2][$soonest] = $newitem;
   // Sort array by start time
   ksort($employees[$bestemployee][2]); 
   $eft = $soonest+$duration*60+$drying*60 ;   
   echo "Calculated eft for $productid is ".date("Y-m-d H:i:s",$eft)."\n";

  } else {
   // There are no sub products, so we buy this direct.
  }
   $stock[$productid] = $stock[$productid]+$qty;
 
 } else {
  // We have some in stock
  echo "Already in stock : ";
  
 }
 return array($eft,$cnt);
}

function takeoutoffwork() {
	global $employees; 
	// Assume everyone is at work all of the time unless the time is outside the ATT periods
	// So fill in 'OFFWORK' periods.
	
	// Start with everyone busy for next 10 years
	foreach($employees as $id=>$item) {
	 $employees[$id][2][strtotime(dtoiso().' 00:00:00')] =
	   array('MAKE'=>'NOTHING',
		      'SKILL'=>'OFFWORK',
					'ORDERLINE'=>'NONE',
					'FINISHTIME'=>strtotime('2020-12-31 23:59:59')
					);
	}
	$sql = "select empid,schedulestarttime,scheduleendtime from work where processid='ATT' and scheduleendtime > now() order by schedulestarttime";
	// Squeeze in gaps where people attend
	$array = sqlreadarray($sql);
	
	foreach ($array as $id=>$item) {
	 $employeeitem = $employees[$item[0]];
	 $fromtime = max(strtotime($item[1]),time());
	 $totime = strtotime($item[2]);
	 foreach ($employeeitem[2] as $starttime=>$record) {
	  if ($fromtime > $starttime && $totime < $record['FINISHTIME']) {
	   // Create a new record
	   $newrecord = $record;
	   $record['FINISHTIME'] = $fromtime ;
	   $employees[$item[0]][2][$starttime] = $record;
	   $employees[$item[0]][2][$totime] = $newrecord;
	  }
	 }
	}
		
}

function write() {

// Writes everything away.
// Start by deleting anything which is not an attendance record.
// TODO : Needs to be faster still.
 $sql = "delete from work where processid <> 'ATT' and starttime = '0000-00-00 00:00:00'";
 $ans = sqlexec($sql);
 global $employees,$depends,$dependsqty;
 $dblink = getconn();
 $atts = 15;
 
 foreach ($employees as $id=>$item) {
  if ($id == "NOBODYCANDOIT") {
   // TODO : Report the error
   xd($id);
   xd($item[2]);
  } else {
   foreach ($item[2] as $starttime=>$rec) {
    if ($rec['SKILL'] != 'ATT' && $rec['SKILL'] != 'OFFWORK' ) {
     $h = array();
		 $h[0] = $rec['CNT'];
		 $h[1] = $item[1];
		 $h[2] = "0";
		 $h[3] = date("Y-m-d H:i:s");
		 $h[4] = "";
		 $h[5] = $item[0];
		 $h[6] = $rec['SKILL'];
		 $h[7] = $rec['MAKE'];
		 $h[8] = $rec['ORDERLINE'];
		 $h[9] = '0000-00-00 00:00:00';
		 $h[10] = '0000-00-00 00:00:00';
		 $h[11] = date("Y-m-d H:i:s",$starttime);
		 $h[12] = date("Y-m-d H:i:s",$rec['FINISHTIME']);
		 $h[13] = @$depends[$rec['CNT']]+0;
		 $h[14] = @$dependsqty[$rec['CNT']]+0;
     $stmt = "insert into work values (";
     for ($i=0;$i<$atts-1;$i++) {
      $stmt .= "'".$h[$i]."',";
     }
 	   $stmt .= "'".$h[$atts-1]."')";
     $result = mysqli_query($dblink,$stmt);
	  }   
	  
	 }
  }
 }
  mysqli_close($dblink);
}
?>